package zzps.exeed.kernel.convert.impl;

import zzps.exeed.kernel.convert.Convert;
import zzps.exeed.kernel.convert.Converter;
import zzps.exeed.kernel.convert.ConverterRegistry;
import zzps.exeed.kernel.tool.ClassTool;
import zzps.exeed.kernel.tool.ReflectTool;
import zzps.exeed.kernel.tool.StrTool;

import java.lang.reflect.Type;
import java.util.*;

public class CollectionConverter implements Converter<Collection<?>> {
    /** 集合类型 */
    private final Type collectionType;
    /** 集合元素类型 */
    private final Type elementType;

    public CollectionConverter(Type collectionType) {
        this.collectionType = collectionType;
        this.elementType = ClassTool.getTypeArgument(collectionType);
    }

    @Override
    public Collection<?> convert(Object value) {
        Class<?> rawClass = ClassTool.getRawClass(collectionType);
        if (value.getClass().isArray()) {
            Object[] objects = (Object[]) value;
            Collection<?> collection = create(rawClass, objects.length);
            for (int i = 0; i < objects.length; i++) {
                Object object = objects[i];
                ConverterRegistry converterRegistry = ConverterRegistry.get();
                collection.add(converterRegistry.convert(elementType, object));
            }
            return collection;
        }
        if (value instanceof CharSequence){
            List<String> stringList = StrTool.split(value.toString(), ',');
            Collection<?> collection = create(rawClass, stringList.size());
            for (int i = 0; i < stringList.size(); i++) {
                Object object = stringList.get(i);
                ConverterRegistry converterRegistry = ConverterRegistry.get();
                collection.add(converterRegistry.convert(elementType, object));
            }
            return collection;
        }
        return null;
    }

    private <T> Collection<T> create(Class<?> collectionType,int size) {
        final Collection<T> list;
        if (collectionType.isAssignableFrom(List.class)) {
            list = new ArrayList<>(size);
        }
        else if (collectionType.isAssignableFrom(Set.class)) {
            list = new HashSet<>(size);
        }
        else {
            list = (Collection<T>) ReflectTool.newInstance(collectionType);
        }
        return list;
    }

    private <T> void add(Object value) {

    }
}
